package com.algorithm.datastructure;

import java.util.Arrays;
import java.util.Iterator;
import java.util.function.Consumer;
import java.util.stream.IntStream;

/**
 * 动态数组
 */
public class DynamicArray implements Iterable<Integer> {
    private int size = 0; //逻辑大小
    private int capacity = 10; //容量
    private int[] array = {};

    public void addLast(int element) throws Exception {
//        array[size]=element;
//        size++;
        add(size, element);
    }

    public void add(int index, int element) throws Exception {
        checkAndGrow();

        if (index >= 0 && index < size) {
            System.arraycopy(array, index,
                    array, index + 1, size - index);
        }
        if (index < 0 || index > size) {
            throw new Exception("输入的索引不合法");
        }
        array[index] = element;
        size++;
    }

    private void checkAndGrow() {
        if (size == 0) {
            array = new int[capacity];
        } else if (size == capacity) {
            capacity += capacity >> 1;
            int[] newArray = new int[capacity];
            System.arraycopy(array, 0,
                    newArray, 0, size);
            array = newArray;
        }
    }

    public int remove(int index) throws Exception {
        if (index < 0 || index >= size) {
            throw new Exception("输入的索引不合法");
        }
        int removed = array[index];

        if (index < size - 1) {
            System.arraycopy(array, index + 1,
                    array, index, size - index - 1);
        }
        size--;
        return removed;
    }


    public int get(int index) throws Exception {
        if (index < 0 || index >= size) {
            throw new Exception("输入的索引不合法");
        }
        return array[index];
    }

    public String getAll() throws Exception {
        return Arrays.toString(array);
    }

    public void foreach(Consumer<Integer> consumer) {
        for (int i = 0; i < size; i++) {
//            System.out.println(array[i]);
            consumer.accept(array[i]);
        }
    }

    @Override
    public Iterator<Integer> iterator() {
        return new Iterator<Integer>() {
            int i = 0;

            @Override
            public boolean hasNext() { // 判断是否还有下一个元素
                return i < size;
            }

            @Override
            public Integer next() { //返回当前元素,并移动到下一个元素
                return array[i++];
            }
        };
    }

    public IntStream stream() {
        return IntStream.of(Arrays.copyOfRange(array, 0, size));
    }

    public static void main(String[] args) {
        try {
            DynamicArray darray = new DynamicArray();
            darray.add(0, 1);
            darray.add(0, 2);
            darray.addLast(5);
            System.out.println(darray.getAll());

            System.out.println("forEach:");
            darray.forEach((element) -> {
                System.out.println(element);
            });

            System.out.println("foreach:");
            darray.foreach((element) -> {
                System.out.println(element);
            });

            System.out.println("Iterator:");
            for (Integer element : darray) { //hasNext() next()
                System.out.println(element);
            }

            System.out.println("stream:");
            darray.stream().forEach(element -> {
                System.out.println(element);
            });

            int remove = darray.remove(0);
            System.out.println("remove:" + remove);
            darray.stream().forEach(element -> {
                System.out.println(element);
            });
            System.out.println("————————————");
            //测试扩容
            DynamicArray darray2 = new DynamicArray();
            System.out.println("默认size:" + darray2.size);
            System.out.println("默认capacity：" + darray2.capacity);
            for (int i = 0; i < 12; i++) {
                darray2.add(i, i + 1);
                System.out.println("扩容中size:" + darray2.size);
                System.out.println("扩容中capacity：" + darray2.capacity);
            }
            System.out.println("扩容后capacity：" + darray2.capacity);
            System.out.println(Arrays.toString(darray2.array));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
